# -*- coding: utf-8 -*-
import atexit
import threading


class BufferedMixin:
    """缓存定时执行"""

    def __init__(self, buffer_size=100, buffer_flush_timing=5):
        self.buffer = []
        self.buffer_size = buffer_size
        self.last_record = None

        # clean exit event
        atexit.register(self.destroy)

        self.buffer_lock = threading.RLock()

        # call at interval function
        def call_repeatedly(interval, func, *args):
            stopped = threading.Event()

            # actual thread function
            def loop():
                while not stopped.wait(interval):
                    func(*args)

            timer_thread = threading.Thread(target=loop)
            timer_thread.daemon = True
            timer_thread.start()
            return stopped.set, timer_thread

        # launch thread
        self._timer_stopper, self.buffer_timer_thread = call_repeatedly(buffer_flush_timing, self.flush_records)

    def append(self, record):
        self.last_record = record
        self.add_to_buffer(record)
        if len(self.buffer) >= self.buffer_size:
            self.flush_records()

    def add_to_buffer(self, record):
        self.buffer_lock.acquire()
        self.buffer.append(record)
        self.buffer_lock.release()

    def flush_records(self):
        raise NotImplementedError('must be implemented in subclass')

    def empty_buffer(self):
        del self.buffer
        self.buffer = []

    def destroy(self):
        if self._timer_stopper:
            self._timer_stopper()

        self.flush_records()
